﻿
// 文件（系统）对话框Dlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "文件（系统）对话框.h"
#include "文件（系统）对话框Dlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// C文件系统对话框Dlg 对话框

//定义 静态变量的消息：（消息本身是常量，是宏   在这里写静态变量就可以了）：
//注册一个消息：
static UINT WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING);



C文件系统对话框Dlg::C文件系统对话框Dlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MY_DIALOG, pParent),
	m_color(RGB(0,0,64))	//文本颜色默认是骚粉色；
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void C文件系统对话框Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(C文件系统对话框Dlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_COMMAND(ID_menu1_new, &C文件系统对话框Dlg::Onmenu1new)
	ON_COMMAND(ID_menu1_open, &C文件系统对话框Dlg::Onmenu1open)
	ON_COMMAND(ID_menu1_save, &C文件系统对话框Dlg::Onmenu1save)
	ON_COMMAND(ID_menu1_resave, &C文件系统对话框Dlg::Onmenu1resave)
	ON_COMMAND(ID_menu1_set, &C文件系统对话框Dlg::Onmenu1set)
	ON_COMMAND(ID_menu1_print, &C文件系统对话框Dlg::Onmenu1print)
	ON_COMMAND(ID_menu1_exit, &C文件系统对话框Dlg::Onmenu1exit)
	ON_WM_SIZE()

	ON_COMMAND(ID_menu3_color, &C文件系统对话框Dlg::Onmenu3color)
	ON_WM_CTLCOLOR()
	ON_COMMAND(ID_menu3_font, &C文件系统对话框Dlg::Onmenu3font)
	ON_COMMAND(ID_menu2_find, &C文件系统对话框Dlg::Onmenu2find)
	ON_COMMAND(ID_menu2_replace, &C文件系统对话框Dlg::Onmenu2replace)

	ON_REGISTERED_MESSAGE(WM_FINDREPLACE, &C文件系统对话框Dlg::OnFindReplace)
	ON_WM_CLOSE()
END_MESSAGE_MAP()


// C文件系统对话框Dlg 消息处理程序

BOOL C文件系统对话框Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void C文件系统对话框Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR C文件系统对话框Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



//排除退出干扰：
//1.Enter键：
void C文件系统对话框Dlg::OnOK()
{
	// TODO: 在此添加专用代码和/或调用基类
	//MessageBox(L"return");
	//CDialogEx::OnOK();
}

//2.esc键：
BOOL C文件系统对话框Dlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (WM_KEYDOWN == pMsg->message &&
		VK_ESCAPE == pMsg->wParam)
	{
		//MessageBox(L"esc键");
		return true;
	}

	return CDialogEx::PreTranslateMessage(pMsg);
}


void C文件系统对话框Dlg::Onmenu1new()
{
	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
	int nLength = pEdit->GetWindowTextLength();

	// 判断长度是否为0，如果部位0，则新建文本需要保存之前编辑过的文本
	if(nLength != 0)
	{
		if (IDYES == MessageBox(L"是否保存已创建的文档？", L"tips", MB_YESNO | MB_ICONINFORMATION))
		{
			Onmenu1save();
			pEdit->SetWindowText(_T(""));
		}
		else
			return;
	}
	else
	{
		MessageBox(L"该文档已是最新创建的！", L"tips",MB_OK);
	}

}


void C文件系统对话框Dlg::Onmenu1open()
{
	// TODO: 在此添加命令处理程序代码
	//注意：_T(***) 的格式是兼容字符集
	CFileDialog dlg(true, _T("TXT"), _T("666"),
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT,
		_T("文本文件(*.txt)|*.txt| 所有文件(*.*) | *.*| TPEG图片(*.jpg)|*.jpg||"),
		this);

	//点击了取消按钮：
	if (IDCANCEL == dlg.DoModal())
		return;


	//获取一个 或多个 打开文件的路径 并分别弹窗输出：
	CString path = dlg.GetPathName();

	POSITION pos = dlg.GetStartPosition();
	while (pos)
	{
		path = dlg.GetNextPathName(pos);
		//MessageBox(path);

	}


	//打开文件：
	CFile file;
	file.Open(path /*文件路径*/, CFile::modeRead /*只读的方式*/);

	

#if 0

	//读取文件内容：
	CString buff;


	wchar_t temp[1024];
	//char temp[1024];
	/*
	要注意字符集
	注意：如果使用的是Unicode字符集, 那么temp字符串的就该是wchar_t的类型，那么读取到的内容再读取到文本编辑框的内容就一定是乱码，
			设置为多字节字符集，把temp的类型改为char类型，就不会读取乱码了
				在Unicode字符集设置的L"**"格式 可以改为 _T(***)格式，这是兼容字符集，在多字节字符集和Unicode字符集里都不会报错
	
	数据本身是二进制的	从二进制到字符 有一个转换 转换的依据是ASCII码
		字符用一个字节来表示 0 - 255，例如： 'a'	97;'0'	48 等
		而汉字在多字节字符集下 用两个字符表示；

		宽字节字符集：
			即 不管是英文 数字 还是汉字 通通都是2字节
	可以理解为：
		unicode 是宽字节；	ansi 是多字节；	utf_8 是兼容字符集（国际标准）；

	*/
	//字符集和字符编码都要匹配；
	/*
	字符编码：
		
	
	*/
	int r;

	while (1)
	{
		memset(temp, 0, sizeof(temp));		//去掉读取空间1024 除内容外多余的乱码		置空函数


		r = file.Read(temp, 1024);	//把文件内的内容读取给temp，如果file有内容则返回非0的值
		if (r > 0)
		{
			buff += temp;	//把要读取到内容给到buff；
		}
		else
		{
			break;
		}

	}

#endif

	//ansi 转 unicode:
	int nlength = file.GetLength();
	char* pbuffer = new char[nlength + 1];
	memset(pbuffer, 0, nlength + 1);		//清零操作

	char temp[1024];
	int r;				//判断读取成功与否

	while (1)
	{
		memset(temp, 0, sizeof(temp));		//去掉读取空间1024 除内容外多余的乱码		置空函数


		r = file.Read(temp, 1024);	//把文件内的内容读取给temp，如果file有内容则返回非0的值
		if (r > 0)
		{
			strcat(pbuffer, temp);
		}
		else
		{
			break;
		}

	}

	CCharSet set;
	wchar_t* wstr;
	wstr = set.ansiTounicode(pbuffer);


	//关闭文件：
	file.Close();

	//设置文本编辑框内容：
	SetDlgItemText(IDC_EDIT1, wstr);



	delete[] pbuffer;
	delete[] wstr;
}


void C文件系统对话框Dlg::Onmenu1save()
{
	// TODO: 在此添加命令处理程序代码

	//注意：_T(***) 的格式是兼容字符集
	CFileDialog dlg(false, _T("txt"), _T("Are_you_serious"),
		OFN_OVERWRITEPROMPT,
		_T("文本文件(*.txt)|*.txt| 所有文件(*.*) | *.*| TPEG图片(*.jpg)|*.jpg||"),
		this);

	//点击了取消按钮：
	if (IDCANCEL == dlg.DoModal())
		return;

	//获取一个 或多个 打开文件的路径 并分别弹窗输出：
	CString path = dlg.GetPathName();


	//打开文件：
	CFile file;
	file.Open(path, CFile::modeWrite/*只写的方式*/ | CFile::modeCreate	/*创造文件方式*/ );


	//搞个保存内容提示弹窗：
	CString str;
	GetDlgItemText(IDC_EDIT1,str);
	MessageBox(str,L"tips");

#if 0
	//没什么用处
	wchar_t* pwstr = new wchar_t[str.GetLength() + 1];
	memset(pwstr, 0, sizeof(wchar_t) * (str.GetLength() + 1));
#endif 


	CCharSet set;
	char* pstr = set.unicodeToansi(str.GetBuffer());


	file.Write(pstr, str.GetLength());



	file.Close();
	delete[] pstr; 

}


//和保存操作一样
void C文件系统对话框Dlg::Onmenu1resave()
{
	CFileDialog dlg(false, _T("txt"), _T("Are_you_serious"),
		OFN_OVERWRITEPROMPT,
		_T("文本文件(*.txt)|*.txt| 所有文件(*.*) | *.*| TPEG图片(*.jpg)|*.jpg||"),
		this);

	//点击了取消按钮：
	if (IDCANCEL == dlg.DoModal())
		return;

	//获取一个 或多个 打开文件的路径 并分别弹窗输出：
	CString path = dlg.GetPathName();


	//打开文件：
	CFile file;
	file.Open(path, CFile::modeWrite/*只写的方式*/ | CFile::modeCreate);

	CString str;
	GetDlgItemText(IDC_EDIT1, str);


	MessageBox(str, L"tips");

	CCharSet set;
	char* pstr = set.unicodeToansi(str.GetBuffer());

	file.Write(pstr, str.GetLength());


	file.Close();
	delete[] pstr;
}


void C文件系统对话框Dlg::Onmenu1set()
{
	// TODO: 在此添加命令处理程序代码
	MessageBox(L"还没搞");
}


void C文件系统对话框Dlg::Onmenu1print()
{
	// TODO: 在此添加命令处理程序代码
	if (IDYES == MessageBox(L"已打印...", L"tips", MB_YESNO | MB_ICONINFORMATION))
		return;
	else
	{
		MessageBox(L"傻逼，你会？？？？", L"tips");
		return;
	}
}


void C文件系统对话框Dlg::Onmenu1exit()
{
	// TODO: 在此添加命令处理程序代码
	//注意：_T(***) 的格式是兼容字符集
	if(IDYES == MessageBox(_T("保存了没"),_T("tips"),MB_YESNO | MB_ICONINFORMATION))
		CDialogEx::OnOK();		//退出函数
}


//如果拖拽对话框，文本编辑框不会跟着改变，所以用Onsize来实现改变：
void C文件系统对话框Dlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);	//获取对话框的长和宽
#if 1
	CWnd* pWnd = GetDlgItem(IDC_EDIT1);
	if(pWnd)
		pWnd->MoveWindow(0, 0, cx, cy);	//改变文本编辑器的长和宽
#else		//另一种方式

	CRect rect;
	this->GetClientRect(&rect);
	CWnd* pWnd = GetDlgItem(IDC_EDIT1);
	if (pWnd)
		pWnd->MoveWindow(0, 0, cx, cy);
#endif

	
}




void C文件系统对话框Dlg::Onmenu3color()
{
	// TODO: 在此添加命令处理程序代码
	CColorDialog colorDlg;

	//点击了取消按钮
	if (IDCANCEL == colorDlg.DoModal())
		return;

	COLORREF color = colorDlg.GetColor();

	//得到控件的颜色选择
	m_color = color;




}


//可以去设置控件的颜色：
HBRUSH C文件系统对话框Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  在此更改 DC 的任何特性

	// TODO:  如果默认的不是所需画笔，则返回另一个画笔

	switch (pWnd->GetDlgCtrlID())	//获取控件的id：
	{
	case IDC_EDIT1:				//只有当id是示例遍历框的时候才去设置它
		pDC->SetTextColor(m_color);

		break;

	default:
		break;
	}


	return hbr;
}


//设置当前文本的字体：
void C文件系统对话框Dlg::Onmenu3font()
{
	// TODO: 在此添加命令处理程序代码
	CFontDialog dlg;

	//点击了取消按钮：
	if (IDCANCEL == dlg.DoModal())
		return;


#if 0
	CFont font;
	font.CreatePointFont(dlg.GetSize(), dlg.GetFaceName());

	GetDlgItem(IDC_EDIT1)->SetFont(&font);
#else

	CFont font;
	//font.CreatePointFont(dlg.GetSize(), dlg.GetFaceName());

	LOGFONT logfont;
	CFont* pwnfont = GetFont();
	pwnfont->GetLogFont(&logfont);

	logfont.lfHeight = -MulDiv(dlg.GetSize() / 10,
		GetDeviceCaps(GetDC()->m_hDC,LOGPIXELSX),72);	//大小

	wcscpy(logfont.lfFaceName, dlg.GetFaceName());



	if (dlg.IsItalic())
	{
		logfont.lfItalic = true;
	}
	if (dlg.IsBold())
	{
		logfont.lfWeight = FW_BOLD;
	}
	



	font.CreateFontIndirect(&logfont);

	GetDlgItem(IDC_EDIT1)->SetFont(&font);




#endif



}


void C文件系统对话框Dlg::Onmenu2find()
{
	// TODO: 在此添加命令处理程序代码


	//查找函数对话框
	CFindReplaceDialog* pfindDlg = new CFindReplaceDialog;
	pfindDlg->Create(true/*如果是true 就是查找，如果是false 就是替换*/, NULL, NULL);
	m_isFind = true;
	pfindDlg->FlashWindow(SW_SHOW);



}


void C文件系统对话框Dlg::Onmenu2replace()
{
	// TODO: 在此添加命令处理程序代码

	//替换函数对话框
	CFindReplaceDialog* preplaceDlg = new CFindReplaceDialog;
	preplaceDlg->Create(false/*如果是true 就是查找，如果是false 就是替换*/, NULL, NULL);
	m_isFind = false;
	preplaceDlg->FlashWindow(SW_SHOW);
}


//查找和替换的消息映射比较特殊 需要我们自己生明定义还有声明消息处理；
//查找和替换的消息映射函数（查找和替换共用）



LRESULT C文件系统对话框Dlg::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
	CFindReplaceDialog* pfindreplace = CFindReplaceDialog::GetNotifier(lParam);
	if (NULL == pfindreplace)			//点击了取消键，返回查找 or 替换对话框
		return 0;


	//获取到edit控件：
	CEdit* pedit = (CEdit*)GetDlgItem(IDC_EDIT1);

	//关闭查找对话框：
	if (pfindreplace->IsTerminating())		//IsTerminating —— 如果用户决定终止对话框，则为非零；否则为 0。
	{
		pfindreplace = NULL;
		return 0;
	}

	//是否向下搜索
	BOOL isdown = pfindreplace->SearchDown();
	
	//是否匹配大小写
	BOOL isMath = pfindreplace->MatchCase();

	//是否全文匹配
	BOOL isMatchHoleWorld = pfindreplace->MatchWholeWord();

	//用来查找的字符串：
	CString strfindstring;
	strfindstring = pfindreplace->GetFindString();




	//在 往上找中用到的类型转换：
	wchar_t* psz = static_cast<wchar_t*>(strfindstring.GetBuffer());

	//用来替换的字符串：
	CString strReplacestring = pfindreplace->GetReplaceString();


	//获取edit文本：文本编辑器里的文本
	CString strContent;
	pedit->GetWindowText(strContent);

	//获取要差宅的文本长度

	int nLength =strfindstring.GetLength();
	int startIndex = 0;
	int endIndex = 0;

	static bool del = false;
	static int startIndex_up = strContent.GetLength();
	static int endIndex_up = endIndex;

	//匹配

	if (m_isFind)	//查找
	{
		if (isdown)		//往下找：
		{
			//获取光标位置：
			pedit->GetSel(startIndex, endIndex);
			//先找当前位置：
			startIndex = strContent.Find(strfindstring, endIndex);
			//往下找：
			if (-1 != startIndex)		//找到了:
			{
				//设置光标：
				pedit->SetSel(startIndex,
					startIndex + nLength);

				pedit->SetFocus();

			}
			else                       //没找到:
			{
				startIndex = strContent.Find(strfindstring, 0);		//如果没找到，就从当前位置（没找到位)的下一位开始找，strContent.Find(strfindstring, 0) —— 表示没找到的位置；
				if (-1 == startIndex)		//如果还没有找到
				{
					//还没找到：
					MessageBox(L"找不到");
					return 0;

				}
				else                       //重复找到了的操作
				{
					//设置光标：
					pedit->SetSel(startIndex, startIndex + nLength);

					pedit->SetFocus();
				}

			}
			
		}

		else         //往上找
		{
			strContent = strContent.Mid(0, startIndex_up);

			//获取光标位置：
			pedit->GetSel(startIndex_up, endIndex_up);
			//先找当前位置：
			
			startIndex_up = strContent.ReverseFind(*psz	/* strfindstring 的类型转换 再解引用 */	);
			//往下找：
			if (-1 != startIndex_up)		//找到了:
			{
				//设置光标：
				pedit->SetSel(startIndex_up,startIndex_up + nLength);
				pedit->SetFocus();
				del = true;
			}
			else if(del)
			{
				CString strContent_next;
				pedit->GetWindowText(strContent_next);
				startIndex_up = strContent_next.GetLength();
				endIndex_up = endIndex;
			}
			else                       //没找到:
			{
				
				MessageBox(L"找不到");
				return 0;
			}
		}

	}
	else            //替换
	{
		//点击了查找按钮：
		if (pfindreplace->FindNext())
		{
			//MessageBox(L"查找下一个");
			//获取光标位置
			pedit->GetSel(startIndex, endIndex);
			//先找当前位置
			startIndex = strContent.Find(strfindstring, endIndex);
			if (-1 != startIndex)		//找到了:
			{
				//设置光标：
				pedit->SetSel(startIndex,
					startIndex + nLength);
				pedit->SetFocus();

			}
			else                       //没找到:
			{
				startIndex = strContent.Find(strfindstring, 0);		//如果没找到，就从当前位置（没找到位)的下一位开始找，strContent.Find(strfindstring, 0) —— 表示没找到的位置；
				if (-1 == startIndex)		//如果还没有找到
				{
					//还没找到：
					MessageBox(L"找不到");
					return 0;
				}
				else                       //重复找到了的操作
				{
					//设置光标：
					pedit->SetSel(startIndex, startIndex + nLength);
					pedit->SetFocus();
				}

			}


		}


		//点击了替换按钮
		if (pfindreplace->ReplaceCurrent())
		{
			//MessageBox(L"替换下一个");
			startIndex = strContent.Find(strfindstring,endIndex);
			if (-1 == startIndex)			//没有找到
			{
				MessageBox(L"都没有找到，替换个毛线");
			}
			else                           //找到了
			{
				endIndex = startIndex + nLength;

				//把 startIndex和endIndex中间的文本替换成 strReplaceString
				CString strleft, strright, strmid;
				strleft = strContent.Left(startIndex);
				strmid = strContent.Mid(startIndex, nLength);
				strright = strContent.Right(strContent.GetLength() -endIndex);


				strContent = strleft + strReplacestring + strright;
				pedit->SetWindowText(strContent);

			}

		}


		//点击了替换所有按钮
		if (pfindreplace->ReplaceAll())
		{
			//MessageBox(L"替换所有");

			int myCount = strContent.Replace(strfindstring, strReplacestring);
			pedit->SetWindowText(strContent);

			CString str;
			str.Format(L"替换了%d", myCount);
			MessageBox(str,L"tips",MB_OK | MB_ICONINFORMATION);

		}
	}


	//MessageBox(L"查找");

	return 1;
}




//x键退出程序是否保存操作：
void C文件系统对话框Dlg::OnClose()
{
	//如果文本编译器中有内容，判断是否保存
	CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT1);
	int nLength = pEdit->GetWindowTextLength();
	if (nLength != 0)
	{
		if (IDYES == MessageBox(L"你tm保存不啊？？？", L"tips", MB_YESNO | MB_ICONINFORMATION))
		{
			Onmenu1save();
		}
	}
	




	CDialogEx::OnClose();
}
